#include "gpg.h"
//#include "t-support.h"

gpgme_error_t passphrase_cb (void * opaque, const char *uid_hint, const char *passphrase_info, int last_was_bad, int fd)
{
	int passlen = strlen(password);
	char * endl = "\n";
	int offset = 0;
	int ret;
	do
	{
		ret = write(fd, &password[offset], passlen - offset);
		if (ret > 0)
			offset += ret;
	}
	while (ret > 0 && offset != passlen);
	write(fd, endl, 1);
	return offset == passlen ? 0 : gpgme_error_from_errno(errno);
}
void setup_gpg()
{
	gpgme_check_version(NULL); //Initialize GPG
	setlocale(LC_ALL, ""); //Setup the locale infos
	gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES,NULL));
	gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); //Set the engine to use OpenPGP
	//Start the gpg context.
	if (gpgme_new(&ctx) != GPG_ERR_NO_ERROR)
	{
		printf("Could not create context!");
		return ;
	}
	//Select the first private key. We're assuming that there's only one private key...
	gpgme_op_keylist_start(ctx,NULL,1);
	gpgme_op_keylist_next(ctx,&identity);
	gpgme_op_keylist_end(ctx);	
	gpgme_set_armor(ctx,1);
	printf("Using identity of %s\n", identity->uids->name);
	//Set the password for the identity.
	password  = getpass("Enter the password:");
	//Set the identity as a signer.
	gpgme_signers_add(ctx, identity);
	gpgme_set_passphrase_cb(ctx,passphrase_cb, NULL);
}
void encrypt_gpg(char * data, char * buffer)
{
	gpgme_data_t indh, outdh;
	gpgme_error_t err;

	gpgme_data_new_from_mem(&indh, data, strlen(data), 0);
	gpgme_data_new(&outdh);

	gpgme_key_t keys[2] = { recipient, NULL };	
	printf("Encrypting %s to %s\n", data, recipient->uids->name);

	err = 	gpgme_op_encrypt_sign(ctx, keys, GPGME_ENCRYPT_ALWAYS_TRUST, indh, outdh);
	//print_data(outdh);	
	gpgme_data_seek(outdh, 0, SEEK_SET);

	gpgme_data_read(outdh, buffer, GPG_BUFFER_LENGTH);

	gpgme_data_release(indh);
	gpgme_data_release(outdh);
}
void decrypt_gpg_dh(gpgme_data_t indh, char * buffer)
{
	gpgme_verify_result_t result;
	gpgme_data_t outdh;
	gpgme_data_new(&outdh);

	gpgme_op_decrypt_verify(ctx, indh, outdh);
	result = gpgme_op_verify_result(ctx);
	if (gpgme_err_code(result->signatures->validity_reason) != GPG_ERR_NO_ERROR)
	{
		printf("Validation failed.\n");
		return;
	}
	gpgme_data_seek(outdh, 0, SEEK_SET);
	gpgme_data_read(outdh, buffer, GPG_BUFFER_LENGTH);

	gpgme_data_release(outdh);
}
void decrypt_gpg_s(char * data, char * buffer)
{
	gpgme_data_t indh;
	gpgme_data_new_from_mem(&indh, data, strlen(data), 0);
	decrypt_gpg_dh(indh, buffer);
	gpgme_data_release(indh);

}
void get_key(gpgme_key_t key, char * buffer)
{
	gpgme_data_t dh;
	gpgme_data_new(&dh);
	gpgme_key_t keys[2] = { key, NULL};
	gpgme_op_export_keys(ctx, keys, 0, dh);

	gpgme_data_seek(dh, 0, SEEK_SET);
	gpgme_data_read(dh, buffer, 8000);
	gpgme_data_release(dh);
}
void destroy_gpg()
{
	gpgme_release(ctx);
}

